//给定一个排序数组和一个目标值，在数组中找到目标值，并返回其索引。如果目标值不存在于数组中，返回它将会被按顺序插入的位置。 
//
// 请必须使用时间复杂度为 O(log n) 的算法。 
//
// 
//
// 示例 1: 
//
// 
//输入: nums = [1,3,5,6], target = 5
//输出: 2
//
//
// 示例 2:
//
//
//输入: nums = [1,3,5,6], target = 2
//输出: 1
//
//
// 示例 3:
//
//
//输入: nums = [1,3,5,6], target = 7
//输出: 4
// 
//
// 示例 4: 
//
// 
//输入: nums = [1,3,5,6], target = 0
//输出: 0
// 
//
// 示例 5: 
//
// 
//输入: nums = [1], target = 0
//输出: 0
// 
//
// 
//
// 提示: 
//
// 
// 1 <= nums.length <= 104 
// -104 <= nums[i] <= 104 
// nums 为无重复元素的升序排列数组 
// -104 <= target <= 104 
// 
// Related Topics 数组 二分查找 
// 👍 1199 👎 0

package leetcode.editor.cn;
public class P35SearchInsertPosition {
    public static void main(String[] args) {
        Solution solution = new P35SearchInsertPosition().new Solution();
        int[] nums = new int[]{1,3,5,6};
        int target = 5;
//        System.out.println(solution.searchInsert(nums, target));

        int[] nums2 = new int[]{1,3,5,6};
        int target2 = 2;
        System.out.println(solution.searchInsert(nums2, target2));

        int[] nums3 = new int[]{1,3,5,6};
        int target3 = 7;
//        System.out.println(solution.searchInsert(nums3, target3));

        int[] nums4 = new int[]{1,3,5,6};
        int target4 = 0;
        System.out.println(solution.searchInsert(nums4, target4));

        int[] nums5 = new int[]{1};
        int target5 = 0;
//        System.out.println(solution.searchInsert(nums5, target5));
    }
    //leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int searchInsert3(int[] nums, int target) {
        int left = 0, right = nums.length-1;
        int middle = 0;
         while (left <= right) {
             middle = left + ((right - left)>>1);
             if (nums[middle] == target) {
                 break;
             } else if (nums[middle] < target) {
                 left = middle+1;
             } else {
                 right = middle-1;
             }
         }
        if (nums[middle] == target) {
            return middle;
        } else if (nums[middle] < target) {
            return middle+1;
        } else {
            return middle;
        }
    }

    // 最优解
    public int searchInsert(int[] nums, int target) {
        int n = nums.length;
        int left = 0;
        int right = n - 1; // 定义target在左闭右闭的区间里，[left, right]
        while (left <= right) { // 当left==right，区间[left, right]依然有效
            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target 在左区间，所以[left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间，所以[middle + 1, right]
            } else { // nums[middle] == target
                return middle;
            }
        }
        // 分别处理如下四种情况
        // 目标值在数组所有元素之前  [0, -1]
        // 目标值等于数组中某一个元素  return middle;
        // 目标值插入数组中的位置 [left, right]，return  right + 1
        // 目标值在数组所有元素之后的情况 [left, right]， return right + 1
        return right + 1;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

}